#include "VSingerUi.h"
#include "VSingerNavigator.h"
#include "VSingerWall.h"
#include "VSingerEffect.h"
#include "VButton.h"
#include "VSongsUi.h"
#include "VMain.h"
#include "VPicture.h"
#include "VTextureProcessor.h"



VSingerUi::VSingerUi()
{
    _cover = new VSingerCoverEffect;
    _nav = new VSingerNavigator;
    _wall = new VSingerWall;
    _pg = new VPageWidget;
    _swieff = new VButton;

    _swieff->loadTexture(
        VMain::getSkin("singerswitcheffect.png")
    );


    _cover->setVisible(true);
    _wall->setVisible(false);

    _cover->setCoverFlowGeometry(0, 170, VIEWPORT_WIDTH, VIEWPORT_HEIGHT - 270);
    _wall->setGeometry(0, 170, VIEWPORT_WIDTH, VIEWPORT_HEIGHT - 270);
    _nav->setGeometry(0, 50, VIEWPORT_WIDTH, 64);
    _pg->setGeometry(800, 540, AUTOSET, AUTOSET);
    _swieff->setGeometry(50, 540, 64, 64);

    _nav->init();

    _cefct = COVER;

    _pg->setItemPerPage(currentEffect()->item_per_page());
    _pg->setCallback(&VSingerUi::page_callback);

    _swieff->setClickHandler(
        &VSingerUi::switch_effect
    );

    insert(_nav);
    insert(_cover);
    insert(_wall);
    insert(_pg);
    insert(_swieff);
}

VSingerUi::~VSingerUi()
{
    SAFE_RELEASE(_cover);
    SAFE_RELEASE(_nav);
}

VSingerCoverEffect* VSingerUi::getCover(void)
{
    return _cover;
}

VSingerWall* VSingerUi::getWall(void)
{
    return _wall;
}

VSingerNavigator* VSingerUi::getNav(void)
{
    return _nav;
}

VPageWidget* VSingerUi::getPage(void)
{
    return _pg;
}



VSingerEffect* VSingerUi::currentEffect(void)
{
    switch (_cefct)
    {
    case COVER:
        return _cover;
    case WALL:
        return _wall;
    default:
        return NULL;
    };
}

bool VSingerUi::switch_effect(int, int, VWidget*)
{
    VSingerUi* ui =
        (VSingerUi*)VMain::queryUi(UI_SINGER);
    int pos_old = ui->currentEffect()->current_position();

    ui->_cefct =
        ui->_cefct == COVER ?
        WALL : COVER;

    /*VSingerNavigator::switchToSpecialTab(
        0, 0,
        (VButton*)ui->_nav->at(ui->_nav->getCurrentTab())
    );*/

    ui->setupEffect();
    ui->autoSet();

    ui->_cover->setVisible(ui->_cefct == COVER);
    ui->_wall->setVisible(ui->_cefct == WALL);

    ui->_pg->setCurrentItem(pos_old);
    ui->_pg->setItemPerPage(ui->currentEffect()->item_per_page());
    ui->currentEffect()->scroll_to(pos_old);

    return true;
}

void VSingerUi::page_callback(int pg, int it , char dir)
{
    VSingerUi* ui =
        (VSingerUi*)VMain::queryUi(UI_SINGER);

    ui->currentEffect()->scroll_to(it);

    if (dir == PGUP)
    {
        ui->currentEffect()->animate_left();
    }
    else
    {
        ui->currentEffect()->animate_right();
    }

    ui->autoSet();
}

void VSingerUi::click_callback(singer_t* singer)
{
    ind_singer_song_t* ind =
        findInd_singer_song(singer);
    int i;
    VSongsUi* ui = (VSongsUi*)VMain::queryUi(UI_SONGS);

    ui->clear();

    for (i = 0; i != ind->songs_count; ++i)
    {
        ui->push_back(ind->songs[i]);
    }
}

void VSingerUi::autoLoadTexture()
{/*
    int middle = currentEffect()->current_position();
    int bound = int(currentEffect()->item_per_page() * 1.5);
    int releasebound = bound * 2;
    int i = middle - releasebound;

    if (i < 0)
    {
        i = 0;
    }

    for (; i != middle + releasebound; ++i)
    {
        if (i >= currentEffect()->size())
        {
            break;
        }

        if (i < middle - bound || i >= middle + bound)
        {
            releaseTexture(_idarray[i]);
        }
        else
        {
            loadTexture(_idarray[i]);
        }
    }
    */
    VMain::getTexProc()->setRangeCurrentPosition(
        _texture_delegate_range_id,
        currentEffect()->current_position()
    );
}

void VSingerUi::setupEffect(void)
{
    currentEffect()->clear();
    int i = 0;
    for (; i != _idarray.size(); ++i)
    {
        currentEffect()->push_back(
            _idarray[i]);
    }

    currentEffect()->auto_set_position();

    _pg->setItemPerPage(currentEffect()->item_per_page());
    _pg->setItemCount(currentEffect()->size());
    _pg->setCurrentItem(currentEffect()->current_position());

    initializeTextures();
    setupTextureDelegate();
    autoLoadTexture();
}

void VSingerUi::push_back(singer_t* singer)
{
    this->_idarray.push_back(
        singer);
}

void VSingerUi::clear(void)
{
    this->_idarray.clear();
}

void VSingerUi::loadTexture(singer_t* singer)
{
    /*GLuint texture;


    if (singer->texture == VSingerNavigator::getDefaultAvatar()->getTexture())
    {
        if (VMain::loadTexture(
                    VMain::getPicture("singers\\%d.PNG", singer->id), &texture))
        {
            singer->texture = texture;
        }
        else
        {
            singer->texture = VSingerNavigator::getDefaultAvatar()->getTexture();
        }
    }
    
    VMain::getTexProc()->delegateLoad(
        VMain::getPicture("singers\\%d.PNG", singer->id),
        TP_PRIORITY_NORMAL,
        &singer->texture,
        VSingerNavigator::getDefaultAvatar()->getTexture());
        */
}

void VSingerUi::releaseTexture(singer_t* singer)
{
    if (singer->texture != VSingerNavigator::getDefaultAvatar()->getTexture() &&
            singer->texture != INVALID_TEXTURE)
    {
        VMain::deleteTexture(&singer->texture);
        singer->texture = VSingerNavigator::getDefaultAvatar()->getTexture();
    }
    
}

void VSingerUi::releaseAllTexture(void)
{
    int i = 0;
    if (_texture_delegate_range_id != 0) {
        VMain::getTexProc()->deleteDelegateRange(
            _texture_delegate_range_id);
        _texture_delegate_range_id = 0;
    }
/*
    for (; i != _idarray.size(); ++i)
    {
        releaseTexture(_idarray[i]);
    }
    */
}

void VSingerUi::autoSet(void)
{
    _pg->setCurrentItem(currentEffect()->current_position());
    autoLoadTexture();
}

void VSingerUi::initializeTextures(void)
{
    int i = 0;

    for (; i != _idarray.size(); ++i)
    {
        _idarray[i]->texture =
            VSingerNavigator::getDefaultAvatar()->getTexture();
        _idarray[i]->captexture =
            VSingerNavigator::getDefaultAvatar()->getTexture();
    }
}

void VSingerUi::setupTextureDelegate( void )
{
    if (_texture_delegate_range_id != 0) {
        VMain::getTexProc()->deleteDelegateRange(
            _texture_delegate_range_id);
    }

    VMain::getTexProc()->delegateRange(
        &qp_callback,
        &qt_callback,
        _idarray.size(),
        currentEffect()->item_per_page() * 1.5,
        currentEffect()->item_per_page() * 1.5,
        VSingerNavigator::getDefaultAvatar()->getTexture(),
        &_texture_delegate_range_id
        );
}

void VSingerUi::qt_callback( int no, GLuint** texture )
{
    if (!texture) {
        return;
    }

    VSingerUi* ui =
        (VSingerUi*)VMain::queryUi(UI_SINGER);
    if (no < 0 || no >= ui->_idarray.size()) {
        *texture = 0;
    }
    *texture = &(ui->_idarray[no]->texture);
}

void VSingerUi::qp_callback( int no, std::string* filename )
{
    if (!filename) {
        return;
    }

    VSingerUi* ui =
        (VSingerUi*)VMain::queryUi(UI_SINGER);
    if (no < 0 || no >= ui->_idarray.size()) {
        *filename = "";
    }
    *filename =
        VMain::getPicture("singers\\%d.PNG", ui->_idarray[no]->id);
}

// void VSingerUi::clicked( singer_t* singer )
// {
//     find_ind_singer_song();
// }

